> ## Documentation Index
> Fetch the complete documentation index at: https://superdoc-dependabot-npm_and_yarn-npm_and_yarn-e04d5d616f.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error Handling

> Understanding and handling SuperDoc API errors gracefully

## Error Response Format

All SuperDoc API errors follow a consistent JSON structure:

```json
{
  "code": "ERROR_CODE",
  "error": "Error Type",
  "message": "Human-readable error description",
  "requestId": "req_abc123",
  "timestamp": "2024-01-15T10:30:00Z"
}
```

<ResponseField name="code" type="string" required>
  Machine-readable error code for programmatic handling
</ResponseField>

<ResponseField name="error" type="string" required>
  HTTP status text (e.g., "Bad Request", "Unauthorized")
</ResponseField>

<ResponseField name="message" type="string" required>
  Human-readable error description
</ResponseField>

<ResponseField name="requestId" type="string" required>
  Unique identifier for the request (useful for support)
</ResponseField>

<ResponseField name="timestamp" type="string">
  ISO 8601 timestamp when the error occurred
</ResponseField>

## HTTP Status Codes

SuperDoc API uses standard HTTP status codes:

<AccordionGroup>
  <Accordion title="400 Bad Request" icon="exclamation-triangle">
    **Client Error** - Invalid request format or parameters

    Common causes:

    * Missing required parameters
    * Invalid file format
    * Malformed request body
    * File too large
  </Accordion>

  {" "}

  <Accordion title="401 Unauthorized" icon="lock">
    **Authentication Error** - Invalid or missing API key Common causes: - Missing
    `Authorization` header - Invalid API key format - Expired or revoked API key
  </Accordion>

  {" "}

  <Accordion title="403 Forbidden" icon="ban">
    **Authorization Error** - Valid credentials but insufficient permissions
    Common causes: - Plan limitations exceeded - Feature not available in current
    plan - IP address restrictions
  </Accordion>

  {" "}

  <Accordion title="429 Too Many Requests" icon="gauge-high">
    **Rate Limiting** - Request quota exceeded Common causes: - Hourly rate limit
    exceeded - Daily rate limit exceeded - Burst limit exceeded
  </Accordion>

  {" "}

  <Accordion title="500 Internal Server Error" icon="server">
    **Server Error** - Unexpected server-side issue Common causes: - Temporary
    service disruption - Document processing failure - Resource exhaustion
  </Accordion>

  <Accordion title="503 Service Unavailable" icon="exclamation-circle">
    **Service Unavailable** - Temporary service interruption

    Common causes:

    * Scheduled maintenance
    * System overload
    * Dependency failures
  </Accordion>
</AccordionGroup>

## Common Error Codes

### Authentication Errors

<CodeGroup>
  ```json MISSING_AUTH
  {
    "code": "MISSING_AUTH",
    "error": "Unauthorized",
    "message": "Authorization header is required",
    "requestId": "req_abc123"
  }
  ```

  ```json INVALID_API_KEY
  {
    "code": "INVALID_API_KEY",
    "error": "Unauthorized",
    "message": "The provided API key is invalid or has been revoked",
    "requestId": "req_def456"
  }
  ```

  ```json EXPIRED_API_KEY
  {
    "code": "EXPIRED_API_KEY",
    "error": "Unauthorized",
    "message": "The API key has expired. Please generate a new one",
    "requestId": "req_ghi789"
  }
  ```
</CodeGroup>

### File Processing Errors

<CodeGroup>
  ```json INVALID_FILE_TYPE
  {
    "code": "INVALID_FILE_TYPE",
    "error": "Bad Request",
    "message": "Only DOCX files are supported for conversion",
    "requestId": "req_jkl012"
  }
  ```

  ```json FILE_TOO_LARGE
  {
    "code": "FILE_TOO_LARGE",
    "error": "Bad Request",
    "message": "File size exceeds the 25MB limit",
    "requestId": "req_mno345"
  }
  ```

  ```json CORRUPTED_FILE
  {
    "code": "CORRUPTED_FILE",
    "error": "Bad Request",
    "message": "The uploaded file appears to be corrupted and cannot be processed",
    "requestId": "req_pqr678"
  }
  ```

  ```json CONVERSION_FAILED
  {
    "code": "CONVERSION_FAILED",
    "error": "Internal Server Error",
    "message": "Document conversion failed due to processing error",
    "requestId": "req_stu901"
  }
  ```
</CodeGroup>

### Rate Limiting Errors

<CodeGroup>
  ```json RATE_LIMIT_EXCEEDED
  {
    "code": "RATE_LIMIT_EXCEEDED",
    "error": "Too Many Requests",
    "message": "Rate limit exceeded. Try again in 3600 seconds",
    "requestId": "req_vwx234",
    "retryAfter": 3600
  }
  ```

  ```json QUOTA_EXCEEDED
  {
    "code": "QUOTA_EXCEEDED",
    "error": "Forbidden",
    "message": "Monthly quota exceeded. Upgrade your plan or wait for reset",
    "requestId": "req_yzab567"
  }
  ```
</CodeGroup>

## Error Handling Strategies

### Basic Error Handling

<CodeGroup>
  ```javascript JavaScript
  async function convertDocument(file) {
    try {
      const response = await fetch('/v1/convert?format=pdf', {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
        },
        body: formData
      });

      if (!response.ok) {
        const error = await response.json();
        throw new Error(`API Error: ${error.code} - ${error.message}`);
      }

      return await response.blob();

  } catch (error) {
  console.error('Conversion failed:', error.message);
  throw error;
  }
  }

  ```

  ```python Python
  import requests
  from requests.exceptions import RequestException

  def convert_document(file_path, api_key):
      try:
          with open(file_path, 'rb') as f:
              files = {'file': f}
              headers = {'Authorization': f'Bearer {api_key}'}

              response = requests.post(
                  'https://api.superdoc.dev/v1/convert?format=pdf',
                  headers=headers,
                  files=files
              )

          if response.status_code != 200:
              error_data = response.json()
              raise Exception(f"API Error: {error_data['code']} - {error_data['message']}")

          return response.content

      except RequestException as e:
          print(f"Request failed: {e}")
          raise
      except Exception as e:
          print(f"Conversion failed: {e}")
          raise
  ```

  ```php PHP
  <?php
  function convertDocument($filePath, $apiKey) {
      $curl = curl_init();

      curl_setopt_array($curl, [
          CURLOPT_URL => 'https://api.superdoc.dev/v1/convert?format=pdf',
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_POST => true,
          CURLOPT_HTTPHEADER => [
              'Authorization: Bearer ' . $apiKey
          ],
          CURLOPT_POSTFIELDS => [
              'file' => new CURLFile($filePath)
          ]
      ]);

      $response = curl_exec($curl);
      $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
      curl_close($curl);

      if ($httpCode !== 200) {
          $error = json_decode($response, true);
          throw new Exception("API Error: {$error['code']} - {$error['message']}");
      }

      return $response;
  }
  ?>
  ```
</CodeGroup>

### Advanced Error Handling with Retry Logic

<CodeGroup>
  ```javascript Exponential Backoff
  class SuperDocClient {
    constructor(apiKey, maxRetries = 3) {
      this.apiKey = apiKey;
      this.maxRetries = maxRetries;
    }

  async convertWithRetry(file) {
  for (let attempt = 0; attempt < this.maxRetries; attempt++) {
  try {
  return await this.convert(file);
  } catch (error) {
  if (this.shouldRetry(error, attempt)) {
  const delay = this.calculateDelay(attempt);
  await this.sleep(delay);
  continue;
  }
  throw error;
  }
  }
  }

  shouldRetry(error, attempt) {
  if (attempt >= this.maxRetries - 1) return false;

      // Retry on server errors and rate limits
      return error.status >= 500 || error.status === 429;

  }

  calculateDelay(attempt) {
  // Exponential backoff with jitter
  const baseDelay = Math.pow(2, attempt) _ 1000;
  const jitter = Math.random() _ 1000;
  return baseDelay + jitter;
  }

  sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
  }
  }

  ```

  ```python Circuit Breaker Pattern
  import time
  import random
  from enum import Enum

  class CircuitState(Enum):
      CLOSED = 1
      OPEN = 2
      HALF_OPEN = 3

  class CircuitBreaker:
      def __init__(self, failure_threshold=5, recovery_timeout=60):
          self.failure_threshold = failure_threshold
          self.recovery_timeout = recovery_timeout
          self.failure_count = 0
          self.last_failure_time = None
          self.state = CircuitState.CLOSED

      def call(self, func, *args, **kwargs):
          if self.state == CircuitState.OPEN:
              if time.time() - self.last_failure_time > self.recovery_timeout:
                  self.state = CircuitState.HALF_OPEN
              else:
                  raise Exception("Circuit breaker is OPEN")

          try:
              result = func(*args, **kwargs)
              self.on_success()
              return result
          except Exception as e:
              self.on_failure()
              raise

      def on_success(self):
          self.failure_count = 0
          self.state = CircuitState.CLOSED

      def on_failure(self):
          self.failure_count += 1
          self.last_failure_time = time.time()

          if self.failure_count >= self.failure_threshold:
              self.state = CircuitState.OPEN
  ```
</CodeGroup>

### Error Handling Best Practices

<AccordionGroup>
  <Accordion title="Use specific error handling" icon="target">
    Handle different error types with appropriate responses:

    ```javascript
    function handleApiError(error) {
      switch (error.code) {
        case 'RATE_LIMIT_EXCEEDED':
          return scheduleRetry(error.retryAfter);
        case 'FILE_TOO_LARGE':
          return showFileSizeError();
        case 'INVALID_FILE_TYPE':
          return showFileTypeError();
        case 'INVALID_API_KEY':
          return redirectToAuth();
        default:
          return showGenericError();
      }
    }
    ```
  </Accordion>

  <Accordion title="Log errors for debugging" icon="clipboard-list">
    Always log errors with context:

    ```javascript
    function logError(error, context) {
      console.error('SuperDoc API Error:', {
        code: error.code,
        message: error.message,
        requestId: error.requestId,
        timestamp: error.timestamp,
        context: context
      });
    }
    ```
  </Accordion>

  <Accordion title="Provide user-friendly messages" icon="comment">
    Translate technical errors into user-friendly messages:

    ```javascript
    const ERROR_MESSAGES = {
      'INVALID_FILE_TYPE': 'Please select a valid Word document (.docx file)',
      'FILE_TOO_LARGE': 'File size must be less than 25MB',
      'RATE_LIMIT_EXCEEDED': 'Too many requests. Please try again later',
      'CONVERSION_FAILED': 'Unable to convert document. Please try again'
    };
    ```
  </Accordion>

  <Accordion title="Implement graceful degradation" icon="shield">
    Provide alternatives when the API is unavailable:

    ```javascript
    async function convertWithFallback(file) {
      try {
        return await superDocConvert(file);
      } catch (error) {
        if (error.status >= 500) {
          // Fallback to alternative service or queue for later
          return fallbackConverter(file);
        }
        throw error;
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Monitoring and Alerting

### Error Rate Monitoring

Track error rates to identify issues:

```javascript
class ErrorTracker {
  constructor() {
    this.errors = new Map();
    this.window = 60000; // 1 minute
  }

  recordError(errorCode) {
    const now = Date.now();
    const windowStart = now - this.window;

    if (!this.errors.has(errorCode)) {
      this.errors.set(errorCode, []);
    }

    const timestamps = this.errors.get(errorCode);
    timestamps.push(now);

    // Remove old timestamps
    this.errors.set(
      errorCode,
      timestamps.filter((t) => t > windowStart)
    );
  }

  getErrorRate(errorCode) {
    const timestamps = this.errors.get(errorCode) || [];
    return timestamps.length;
  }
}
```

### Health Check Implementation

```javascript
async function healthCheck() {
  try {
    const response = await fetch("https://api.superdoc.dev/v1/health");
    return response.ok;
  } catch (error) {
    return false;
  }
}

// Monitor API health
setInterval(async () => {
  const isHealthy = await healthCheck();
  if (!isHealthy) {
    console.warn("SuperDoc API appears to be down");
    // Trigger alerts or fallback behavior
  }
}, 30000); // Check every 30 seconds
```

## Getting Help

When encountering persistent errors:

<CardGroup cols={2}>
  <Card title="Check Status Page" icon="signal" href="https://status.superdoc.dev">
    Monitor service status and planned maintenance
  </Card>

  <Card title="Contact Support" icon="life-ring" href="mailto:support@superdoc.dev">
    Include the requestId for faster troubleshooting
  </Card>
</CardGroup>

<Warning>
  Always include the `requestId` from error responses when contacting support.
  This helps us quickly locate and diagnose the specific request.
</Warning>

{" "}
